#!/usr/bin/env python3
# -*- coding: utf-8 -*-


import os
import tkinter as tk
from pathlib import Path
from tkinter import filedialog
from tkinter import ttk

import util_theme

import utils


class IPanel:
    """
    面板容器对象 接口类
    """

    def __init__(self, _parent):
        self.frame = ttk.Frame(_parent)

    def get_frame(self):
        return self.frame

    def grid(self, **kw):
        self.frame.grid(kw)

    def grid_forget(self):
        self.frame.grid_forget()


class Start(IPanel):
    """
    界面底部的开始按钮 和 输出活动显示框
    """

    def __init__(self, _parent, **kw):
        IPanel.__init__(self, _parent)
        frame = self.frame

        if 'text' in kw:
            btn_text = kw['text']
        else:
            btn_text = "开始"

        btn_call = kw['command'] if 'command' in kw else ''

        # frame = tk.Frame(_parent, bd=1, padx=0, pady=2)
        # frame.grid(column=1, row=1, sticky=tk.W)

        # 颜色
        c_black = util_theme.COLOR_BLACK
        c_list_bg = util_theme.COLOR_LIST_BG
        txt_width = 81

        # 开始转码 按钮
        create_btn = utils.create_button
        btn_text = "\n\n\n\n\n%s\n\n\n\n" % btn_text
        btn = create_btn(frame, text=btn_text, command=btn_call)

        # listbox 和 scrollBar
        self.v2 = tk.StringVar()
        w = kw['width'] if 'width' in kw else txt_width
        list_box = tk.Listbox(
            frame,
            selectmode=tk.EXTENDED,
            listvariable=self.v2,
            width=w,
            height=10,
            fg=c_black,
            bd=0,
            background=c_list_bg,
            setgrid=1,
            activestyle='none'
        )
        scroll_bar = tk.Scrollbar(frame, orient=tk.VERTICAL)
        # self.scrollBar.set(0.5,1)

        list_box.config(yscrollcommand=scroll_bar.set)
        scroll_bar.config(command=list_box.yview)

        btn.grid(column=4, row=1)
        list_box.grid(column=2, row=1, sticky=tk.W)
        scroll_bar.grid(column=3, row=1, sticky=tk.N + tk.S)

        self.frame = frame
        self.start_btn = btn
        self.list_box = list_box

    def set_state(self, boo):
        utils.set_state(self.start_btn, boo)

    def see(self, num):
        self.list_box.see(num)

    def get_string_var(self):
        return self.v2.get()

    def set_string_var(self, tup):
        self.v2.set(tup)
        self.see(len(tup))

    def update_query(self, q_str, warning=False):
        q_str = utils.get_hms() + " " + q_str
        utils.set_title(q_str)
        if warning:
            ""
        # self.logTxt['fg'] = "#ff5643" if warning else "#0096FF"
        # self.logTxt['text'] = qStr
        tup = tuple([q_str])
        var_str = self.get_string_var()
        if utils.var_is_empty(var_str):
            new_tup = tup
        else:
            v = utils.var_to_list(var_str)
            if len(v):
                new_tup = utils.append_tup(tuple(v), tup)
            else:
                new_tup = tup
        new_arr = list(new_tup)
        tmp_arr = []
        for item in new_arr:
            if item:
                tmp_arr.append(item)
        tup = tuple(tmp_arr)
        self.set_string_var(tup)

    def clear_query(self):
        tup = tuple([''])
        self.set_string_var(tup)


class FolderChooser(IPanel):
    """文件夹选择器
    """

    def __init__(self, _parent, **kw):
        IPanel.__init__(self, _parent)
        frame = self.frame

        text_width = kw['text_width'] if 'text_width' in kw else 80

        # 颜色
        # color = util_theme.COLOR_BLACK
        # wrap_length = 780

        # font_name = '微软雅黑' if utils.is_windows else ''
        # font_size = 7 if utils.is_windows else 12

        # element 1
        label_text = '输出路径：'
        w = 8 if utils.is_mac else 10
        label_txt = ttk.Label(frame, text=label_text, width=w)

        # element 2
        # 文件路径
        self.var_entry = tk.StringVar()
        self.entry = ttk.Entry(frame, textvariable=self.var_entry, width=text_width, state='readonly')

        # element 3
        # 选择文件按钮
        action_btn_text = '浏览…'
        tips = "左键点击 选择文件/目录\n右键点击 前往对应文件/目录"
        action_btn = utils.create_button(frame, text=action_btn_text)
        utils.bind_double(action_btn, self.open_folder_call, tips)

        label_txt.grid(column=1, row=1, sticky=tk.W)
        self.entry.grid(column=2, row=1)
        action_btn.grid(column=3, row=1)

    def open_folder_call(self, e):
        """打开文件夹对话框
        """
        f = self.var_entry.get()
        if not utils.is_right_click(e.num):
            init_dir = f
            folder = filedialog.askdirectory(title='选择目录', initialdir=init_dir)
            if folder:
                folder = utils.pathlib_path(folder)
                self.set_folder(folder)
        else:
            if not f:
                utils.showinfo('你还没有选择目录')
                return
            if not os.path.exists(f):
                utils.showinfo('目录 不存在 %s' % f)
                return
            utils.open_dir(f)

    def paste_right_click(self, _):
        """地址文本 右键粘贴"""
        s = utils.clipboard_get()
        if not s:
            return
        if not os.path.isdir(s):
            utils.showinfo("粘贴版里，未找到文件夹路径！")
            return
        if not os.path.exists(s):
            utils.showinfo("粘贴版里的文件夹路径，不存在！")
            return

        self.set_folder(s)

    def set_folder(self, text):
        """设置文本框上的内容"""
        self.var_entry.set(text)
        tips = text if os.path.exists(text) else text + "\n*此文件夹不存在！"
        utils.tooltip(self.entry, tips)

    def get_folder(self):
        """获得文本框上的内容"""
        return self.var_entry.get()

    def is_ready(self, ng_show):
        """是否勾选，路径是否 ok
        """
        f = self.get_folder()
        is_ng = False
        if not os.path.exists(f):
            is_ng = True
        if is_ng:
            utils.showinfo(ng_show)
        return not is_ng


class FileChooser(IPanel):
    """文件选择器
    参数:
        cb_text {[string]} -- [勾选框上的文字]
        btn_text {[string]} -- [按钮上的文字]
        connect_call {[function]} -- [description]
        action_btn_text {[string]} -- [操作按钮上的文字（点击打开文件对话框）]
        filetypes {[list]} -- [文件类型，例如“[("图片文件", "*.png")]”]
        hasGROOVE {[Boolean]} -- [按钮是否有描边]
    """

    cb = None

    def __init__(self, _parent, **kw):
        IPanel.__init__(self, _parent)
        frame = self.frame

        label_text = kw['label_text'] if 'label_text' in kw else ''
        cb_text = kw['cb_text'] if 'cb_text' in kw else ''
        cb_call = kw['cb_call'] if 'cb_call' in kw else None
        btn_text = kw['btn_text'] if 'btn_text' in kw else ''
        btn_call = kw['btn_call'] if 'btn_call' in kw else None
        action_btn_text = kw['action_btn_text'] if 'action_btn_text' in kw else '...'
        action_btn_call = kw['action_btn_call'] if 'action_btn_call' in kw else None
        file_types = kw['filetypes'] if 'filetypes' in kw else []
        is_folder = kw['isFolder'] if 'isFolder' in kw else False
        text_width = kw['text_width'] if 'text_width' in kw else 80

        # 颜色
        color = util_theme.COLOR_BLACK
        # wrap_length = 780

        # font_name = '微软雅黑' if utils.is_windows else ''
        # font_size = 7 if utils.is_windows else 12

        self.cb_call = cb_call
        has_check = False
        if label_text:
            self.label_txt = tk.Label(frame, text=label_text, fg=color)
            self.label_txt.grid(column=1, row=1, sticky=tk.E)

        # 勾选框 形式
        elif cb_text:
            cb = utils.create_check_button(
                frame,
                text=cb_text,
                command=self.checkbox_call
            )
            cb.grid(column=1, row=1, sticky=tk.W)

            self.cb = cb
            has_check = True

        # 按钮 形式
        elif btn_text:
            btn = utils.create_button(frame, text=btn_text, width=6)
            if btn_call:
                btn.config(command=btn_call)
                utils.tooltip(btn, "点击打开目录", 100, 2000)
            btn.grid(column=1, row=1, sticky=tk.W)
            self.btn = btn

        # 文件路径
        # txt = tk.Label(frame, text='')
        # txt.config(
        #     width=text_width,
        #     height=1,
        #     bd=1,
        #     padx=3,
        #     fg=color,
        #     wraplength=wrap_length,
        #     justify='left',
        #     anchor='w'
        # )
        # txt.grid(column=2, row=1)
        # utils.bind(txt, self.paste_right_click, True)

        self.var_entry = tk.StringVar()
        self.entry = ttk.Entry(frame, textvariable=self.var_entry, width=text_width, state='readonly')
        self.entry.grid(column=2, row=1)

        # 选择文件按钮
        action_btn = utils.create_button(
            frame,
            text=action_btn_text,
            state=tk.DISABLED
        )
        if len(file_types):
            action_btn.config(command=self.open_file_call)
            utils.bind(action_btn, self.right_click_call, True)
            self.filetypes = file_types
        self.action_btn_call = action_btn_call
        if is_folder:
            action_btn.config(command=self.open_folder_call, state=tk.NORMAL)
            utils.bind(action_btn, self.right_click_call, True)

        utils.tooltip(action_btn, "左键点击 选择文件/目录\n右键点击 前往对应文件/目录", 100, 2000)

        action_btn.grid(column=3, row=1)

        # self.txt = txt
        self.action_btn = action_btn
        self.hasCheck = has_check
        self.is_folder = is_folder

    def open_file_call(self):
        """打开文件对话框
        """
        f_type = self.filetypes
        init_dir = str(Path(self.var_entry.get()).parent)
        if len(f_type):
            f = filedialog.askopenfilename(filetypes=f_type, title='选择文件', initialdir=init_dir)
            if f:
                self.var_entry.set(utils.pathlib_path(f))

        if self.action_btn_call is not None:
            self.action_btn_call()

    def open_folder_call(self):
        """打开文件夹对话框
        """
        init_dir = self.var_entry.get()
        folder = filedialog.askdirectory(title='选择目录', initialdir=init_dir)
        if folder:
            folder = utils.pathlib_path(folder)

            self.var_entry.set(folder)

            tips = folder if os.path.exists(folder) else folder + "\n*此目录不存在！"
            utils.tooltip(self.entry, tips)

        if self.action_btn_call is not None:
            self.action_btn_call()

    def checkbox_call(self):
        """点击勾选框
        """
        state = tk.NORMAL if self.cb.is_select() else tk.DISABLED
        self.action_btn['state'] = self.entry['state'] = state
        if self.cb_call is not None:
            self.cb_call()

        # if self.var_cb.get() and self.open_file_call:
        #     self.open_file_call()

    def right_click_call(self, _):
        """
        右键点击 行动按钮
        """
        fp = self.var_entry.get()
        if not fp:
            utils.showinfo('你还没有选择文件/目录')
            return
        if not os.path.exists(fp):
            utils.showinfo('文件/目录 不存在 "{}"'.format(fp))
            return

        if self.is_folder:
            utils.open_dir(fp)
        else:
            utils.open_file(fp, True)

    def set_cb_tooltip(self, tips, delay=500, duration=3000):
        if self.cb is not None:
            utils.tooltip(self.cb, tips, delay, duration)

    def get_text(self):
        """获得文本框上的内容
        """
        return self.var_entry.get()

    def set_text(self, text):
        """设置文本框上的内容
        """
        self.var_entry.set(text)
        tips = text if os.path.exists(text) else text + "\n*此文件不存在！"
        utils.tooltip(self.entry, tips)

    def set_select(self, value_str='0'):
        """设置是否选中,通过字符串的方式
        str='0' 不选中
        str='1' 选中
        """
        if not self.hasCheck:
            return
        # enable = True if value_str == "1" else False
        # self.cb.select() if enable else self.cb.deselect()
        self.cb.set_select(value_str)
        self.checkbox_call()

    def set_select_and_text(self, value_str, text):
        """设置
            1.是否选中,通过字符串的方式
                str='0' 不选中
                str='1' 选中
            2.路径文本框文字
        """
        self.set_select(value_str)
        self.set_text(text)

    def has_select(self):
        """是否选中"""
        return self.cb.is_select()

    def get_select_str(self):
        """是否选中
        选中返回 字符串1，没选中返回 字符串0
        """
        return self.cb.get_select()

    def is_ready(self, ng_show):
        """是否勾选，路径是否 ok
        """
        f = self.get_text()
        is_ng = False
        if self.hasCheck:
            if self.cb.is_select() and not os.path.exists(f):
                is_ng = True
        else:
            if not os.path.exists(f):
                is_ng = True
        if is_ng:
            utils.showinfo(ng_show)
        return not is_ng


if __name__ == "__main__":
    win = tk.Tk()
    win.mainloop()
